---
title: Generate delimited export text
summary: Converts an in-memory collection of objects into delimited (CSV-style) text using reflection.
status: draft
owner: <owner>
last_reviewed: 2026-08-21
library: SAIF.Services.Export
reference_type: embedded
operation_id: OP-EXPORT-001
trigger: Caller invokes ExportServices.GetCSV(Of T) with a populated or empty collection
---

# Generate delimited export text

This operation transforms any `IEnumerable(Of T)` collection into a single delimited text string (CSV by default), using reflection to discover the public properties of `T` at runtime. It runs synchronously, in-memory, whenever a caller (presumed to be a Legal web page or code-behind) needs to render a collection as exportable text, for example to stream back to the browser as a file download.*

| Field | Value |
| --- | --- |
| **Operation ID** | OP-EXPORT-001 |
| **Trigger** | Caller invokes `ExportServices.GetCSV(Of T)` |
| **Inputs** | `inColl As IEnumerable(Of T)`, optional `Delimiter As String = ","`, optional `UseQuotes As Boolean = True` |
| **Outputs** | `String` — delimited header row plus data rows, or an empty string if the input collection is empty |
| **Primary components** | `ExportServices.GetCSV(Of T)` |
| **Entry point** | `SAIF.Services.Export\ExportServices.vb` |

## Steps

1. Accept the `IEnumerable(Of T)` collection plus the optional `Delimiter` (default `,`) and `UseQuotes` (default `True`) arguments.
   - If `inColl` is empty: skip directly to step 6 and return an empty string.
2. Use `TypeDescriptor.GetProperties` on the first item in the collection to obtain the set of public properties of `T` via reflection.
3. Build the header row: for each property, append its name to a `StringBuilder`.
   - If `UseQuotes` is `True`: wrap the name in double quotes, escaping any embedded quote as `""`.
   - Otherwise: append the raw property name.
   - Separate property names with `Delimiter`; terminate the header line with `vbCrLf`.
4. For each item in the collection, re-resolve its `PropertyDescriptorCollection` and, for each property, read its value via `CurrentProperty.GetValue(item)`.
5. Append each property's value to the current data row.
   - If the value is non-null: append its `.ToString()` representation — quoted (with embedded-quote escaping) when `UseQuotes` is `True`, or raw otherwise — separated by `Delimiter`.
   - If the value is null: silently skip it (no placeholder/empty field is emitted).*
     - On this condition: subsequent columns in that row can become misaligned relative to the header row when a null value occurs mid-row.*
   - Terminate each completed data row with `vbCrLf`.
6. If the input collection was empty, return an empty string (no header, no rows).
7. Return the assembled `String` to the caller.

No step in this operation delegates to another SAIF business/application/framework library; all logic is self-contained BCL reflection (`System.ComponentModel.TypeDescriptor`) and string-building (`System.Text.StringBuilder`).

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Caller invokes GetCSV]) --> Check{Collection empty?}
	Check -->|Yes| EndEmpty([Return empty string])
	Check -->|No| Props[Get properties of T via TypeDescriptor]
	Props --> Header[Build header row]
	Header --> Loop[For each item: read property values]
	Loop --> Null{Value is null?}
	Null -->|Yes| Skip[Skip value - no placeholder]
	Null -->|No| Append[Append quoted/raw value]
	Skip --> More{More items?}
	Append --> More
	More -->|Yes| Loop
	More -->|No| EndOk([Return assembled string])
```

## Failure and edge-case behavior
- Empty input collection: returns an empty string with no header row and no data rows.
- Null property value mid-row: silently skipped rather than emitted as an empty placeholder, which can misalign column counts across data rows.*
- No exception handling is present in the method; reflection or `ToString()` failures on individual property values would propagate to the caller.**

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Sources
- `SAIF.Services.Export\ExportServices.vb`
- `.saifdocgen\state\runs\20260821-113120-claims-bof-web-legal\analysis\TSK009-analysis.md`
